home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 072 (1988-11-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 072 (1988-11-15)(Ossowski, Stefan)(DE)(PD).adf / Pcopy / pcopy.c < prev    next >
C/C++ Source or Header  |  1988-08-14  |  15KB  |  533 lines

  1. char *stx[]={
  2.   "  Pcopy 1.0   1 April 88 by D.Reisig",
  3.   "  Pcopy 1.0 is PD",
  4.   "  Made in Holland!"
  5. };
  6.  
  7. #include "pcopy.h"
  8.  
  9. /*
  10.  *  Since no commandline parameters are processed, we may prevent
  11.  *  a call to exit(), by defining _main() here.
  12.  *
  13.  *  We do a call to Init() which sets up all I/O, check patching
  14.  *  sceentitles, loop copy function and if desired, a call to Quit()
  15.  *  which returns all memory and closes all I/O.
  16.  */
  17.  
  18. _main()
  19. {
  20.   register struct IntuiMessage *Mesg;
  21.   register int  message;
  22.  
  23.   if (!Init()){
  24.     SetWindowTitles(WT,-1,stx[0]);
  25.     SetWindowTitles(W1,-1,stx[1]);
  26.     SetWindowTitles(W0,-1,stx[2]);
  27.     ConPutStr(IOHist,"\x9b0 p\n\n\n\n\n\n ");
  28.     while(1){
  29.       MainLoop();
  30.       Mesg=GetMsg(WS->UserPort);
  31.       if (Mesg){
  32.         message=Mesg->Class;
  33.         ReplyMsg(Mesg);
  34.         if (message==CLOSEWINDOW){
  35.           if (!Request("    Pcopy","","stay","away")) break;
  36.         }
  37.       }
  38.     }
  39.   }
  40.   Quit();   /*  return and close everything  */
  41.   return(0);
  42. }   /*  _main  */
  43.  
  44.  
  45. /*
  46.  *  See if somthing happend in the command window, check drives and
  47.  *  set "Now in .." windows. Finally check if a start copy condition
  48.  *  became valid.
  49.  */
  50.  
  51. void MainLoop()
  52. {
  53.   static int d0cnt=-1, d1cnt=-1;
  54.  
  55.   CheckControl(1);  /*  some user command? */
  56.   if (GetDrive(D0)){    /*  disk is present */
  57.     if (d0cnt!=D0->ChgNum){
  58.       ShDName(W0,D0->VolName);
  59.       d0cnt=D0->ChgNum;
  60.     }
  61.   } else{               /*  disk is absent */
  62.     ShDName(W0,0);
  63.     EnAuto=-1;  /*  enable auto start */
  64.   }
  65.   if (GetDrive(D1)){
  66.     if (d1cnt!=D1->ChgNum){
  67.       ShDName(W1,D1->VolName);
  68.       d1cnt=D1->ChgNum;
  69.     }
  70.   } else{
  71.     ShDName(W1,0);
  72.     EnAuto=-1;
  73.   }
  74.   CheckCopy();
  75. }  /*  MainLoop()  */
  76.  
  77.  
  78. /*
  79.  *  React upon windowsizing of the history window.
  80.  *  The gadgets are scanned and some minor (mostly intuition-patches)
  81.  *  actions are taken. Did I do it wrong or isn't intuition that good?
  82.  */
  83.  
  84. void CheckControl(flag)
  85. short flag;
  86. {
  87.   static short Excla=0, HistH=HHS;
  88.   
  89.   if (HistH!=WH->Height){
  90.     HistH=WH->Height;
  91.     RefHist();
  92.   }           /* NowCopy tells us which picture presently is displayed */
  93.   if (GAuto.Flags&SELECTED){
  94.     if (NowCopy){
  95.       RemoveGadget(WS,&GCopy);       /* remove manual start */
  96.       GCopy.Flags&=~SELECTED;        /* no surprises when changed back! */
  97.       DrawImage(WS->RPort,&IMBlnk,16,4*GGH);  /* clear area */
  98.       PrintIText(WS->RPort,&ITCCon,16,4*GGH+2);
  99.       AddGadget(WS,&GUnRd,-1);
  100.       AddGadget(WS,&GNDOS,-1);
  101.       RefreshGadgets(&GUnRd,WS,0);
  102.       NowCopy=0;
  103.     }
  104.   } else{
  105.     if (!NowCopy){
  106.       RemoveGadget(WS,&GNDOS);
  107.       RemoveGadget(WS,&GUnRd);
  108.       DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
  109.       AddGadget(WS,&GCopy,-1);
  110.       RefreshGadgets(&GCopy,WS,0);
  111.       NowCopy=1;
  112.     }
  113.   }
  114.   if ((GAuto.Flags&SELECTED)   /* check for dangerous condition */
  115.     &&!(GNDOS.Flags&SELECTED)
  116.     &&!(GUnRd.Flags&SELECTED)){
  117.     if (!Excla){               /* display alarming exclamation */
  118.       DrawImage(WS->RPort,&IMEcla,160,5*GGH);
  119.       Excla=1;
  120.     }
  121.   }else if (Excla){            /* or remove it */
  122.     DrawImage(WS->RPort,&IMEcOf,160,5*GGH);
  123.     Excla=0;
  124.   }
  125.   if (GD0D1.Flags&SELECTED){   /* set colors and arrow according to  */
  126.     ITDr0.FrontPen=PenB;       /* selected direction  */
  127.     ITDr1.FrontPen=PenA;       /* if selected, change state and deselect  */
  128.     GD0D1.GadgetRender=ArrowB; /* again  */
  129.     GD0D1.SelectRender=ArrowA;
  130.     ArrowA=GD0D1.GadgetRender;
  131.     ArrowB=GD0D1.SelectRender;
  132.     PenA=ITDr0.FrontPen;
  133.     PenB=ITDr1.FrontPen;
  134.     GD0D1.Flags&=~SELECTED;    /* if done deselect gadget  */
  135.     RefOneGadget(&GD0D1,WS,0);
  136.   }
  137.                                /* refresh (deghost) window titles */
  138.   if (!flag){                  /* track window with or without depth g's */
  139.     TxT[SHORTTIME]=' ';
  140.     DrawImage(WT->RPort,&IMTTTL,0,0);
  141.     DrawImage(WT->RPort,&IMTTTL,0,9);
  142.     PrintIText(WT->RPort,&ITT,4,1);
  143.   } else{
  144.     TxT[SHORTTIME]='\0';
  145.     PrintIText(WT->RPort,&ITT,4,1);
  146.   }
  147.   PrintIText(WH->RPort,&ITH,4,1);
  148.   PrintIText(W1->RPort,&IT1,4,1);
  149.   PrintIText(W0->RPort,&IT0,4,1);
  150. } /*  CheckControl  */
  151.  
  152.  
  153. /*
  154.  *  Gather all possible info of a drive and return disk presence.
  155.  */
  156.  
  157. GetDrive(drive)
  158. register DrInfo *drive;
  159. {
  160.   register char *name=(char *)(&CopyBuffer[ROOT_VOLNAME]);
  161.   register int error;
  162.  
  163.   drive->Req.io_Command=TD_CHANGESTATE;
  164.   DoIO(&drive->Req);                            /* is there a disk? */
  165.   if (drive->Present=~drive->Req.io_Actual){
  166.     drive->Req.io_Command=TD_CHANGENUM;
  167.     DoIO(&drive->Req);                      /* did we check it already? */
  168.     if (drive->ChgNum!=drive->Req.io_Actual){    /* no ..  */
  169.       drive->ChgNum=drive->Req.io_Actual;
  170.       drive->DOSDisk=0;
  171.       drive->DOSBoot=0;
  172.       drive->Readable=0;
  173.       error=ReadSec(drive,0,CopyBuffer);    /*  readable?  */
  174.       if (!error||(error!=TDERR_NoSecHdr)){
  175.         drive->Readable=-1;
  176.         if (!error&&((*CopyBuffer==0x444f5300)||(*CopyBuffer==0x4b49434b))){
  177.           drive->DOSBoot=-1;                /*  DOS\0  or KICK  */
  178.           if (!ReadSec(drive,ROOTSECTOR,CopyBuffer)
  179.           &&!CheckSum(CopyBuffer)&&(*name<VOLNAMESIZE)){
  180.             drive->DOSDisk=-1;              /*  Truly Amiga-DOS  */
  181.             strncpy(drive->VolName,name+1,*name);
  182.             drive->VolName[*name]='\0';
  183.           } else  strcpy(drive->VolName,"\x0eNear DOS");
  184.         } else  strcpy(drive->VolName,"\x0eNon DOS");
  185.       } else  strcpy(drive->VolName,"\x0eUnreadable");
  186.       MotorOff(drive);
  187.     }     /* end of other chgnum */
  188.   } else  drive->Present=0;
  189.   return ((int)drive->Present);
  190. } /*  GetDrive()  */
  191.  
  192.  
  193.  
  194. ReadSec(drive,sector,buffer)
  195. register DrInfo *drive; SHORT sector; char *buffer;
  196. {
  197.   drive->Req.io_Command=CMD_READ;
  198.   drive->Req.io_Data=(APTR)buffer; 
  199.   drive->Req.io_Length=TD_SECTOR;
  200.   drive->Req.io_Offset=sector*TD_SECTOR;
  201.   DoIO(&drive->Req);
  202.   return((int)drive->Req.io_Error);
  203. }
  204.  
  205.  
  206. /*
  207.  *  The checksum is OK if we add all longwords in a sector and its
  208.  *  result is zero.
  209.  */
  210.  
  211. CheckSum(Sector)
  212. register ULONG *Sector;
  213. {
  214. register  ULONG Sum;
  215. register  short i;
  216.   for (Sum=0,i=0;i<TD_SECTOR/4;++i) Sum+=Sector[i];
  217.   return(Sum);
  218. }
  219.  
  220.  
  221. /*
  222.  *  This routine does the diskcopy. If succesful, a new title is dispayed
  223.  *  in the drive's window and the name is pushed into the history
  224.  *  buffer/window. A short sound signal put out.
  225.  *  If an error occured, a requester is set up to ask a decision from
  226.  *  the user. If aborted, a special message is displayed in the drive's
  227.  *  window, and the routine is left.
  228.  */
  229.  
  230. DiskCopy(Source,Dest,mod)
  231. register DrInfo *Source, *Dest; short mod;
  232. {
  233.   register int cylinder, byte, error;
  234.   char Errbuf0[64], Errbuf1[64];
  235.   char *name=(char *)(&CopyBuffer[ROOT_VOLNAME]);
  236.  
  237.   OffGadget(&GD0D1,WS,0);     /*  disable source/dest selection  */
  238.   GCopy.Flags|=GADGDISABLED;  /*  disable manual start  */
  239.   if (NowCopy){               /*  Intuition handles it bad - trick needed */
  240.     DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
  241.     RefOneGadget(&GCopy,WS,0);
  242.   }
  243.   D0->Count=D0->ChgNum;       /*  set up for Extended Command  */
  244.   D1->Count=D1->ChgNum;
  245.  
  246.   if (mod==WAIT){             /*  Special case, see manual  */
  247.     DisplayBeep(IntuitionBase->ActiveScreen);
  248.     Delay(100);
  249.   }
  250.  
  251.           /*  This is the cylinder counting loop  */
  252.   for (cylinder=0,byte=0;cylinder<NUMCYLS;++cylinder,byte+=BPCYL){
  253.  
  254.     DrawImage(WT->RPort,&IMTmOn,cylinder*4,12);  /*  track window  */
  255.  
  256. ReadSource:
  257.     if (error=DIOCyl(Source,byte,CopyBuffer,ETD_READ)){
  258.       stci_d(stpcpy(Errbuf0,"Source read error # "),error);
  259.       stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
  260.       Beep();
  261.       if (Request(Errbuf0,Errbuf1,"retry","abort")) goto ReadSource;
  262.       else break;
  263.     }
  264.  
  265.     if (cylinder==ROOTCYL){
  266.       ChangeRoot(CopyBuffer);
  267.       strncpy(Dest->VolName,name+1,*name);
  268.       Dest->VolName[*name]='\0';
  269.       Dest->DOSDisk=-1;
  270.     }
  271.  
  272. WriteDestination:
  273.     if (error=DIOCyl(Dest,byte,CopyBuffer,ETD_FORMAT)){
  274.       stci_d(stpcpy(Errbuf0,"Destination write error # "),error);
  275.       stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
  276.       Beep();
  277.       if (Request(Errbuf0,Errbuf1,"retry","abort")) goto WriteDestination;
  278.       else break;
  279.     }
  280.  
  281.     if (GVerf.Flags&SELECTED){
  282.       Dest->Req.io_Command=ETD_CLEAR;
  283.       DoIO(&Dest->Req);
  284.       if (error=DIOCyl(Dest,byte,CompBuffer,ETD_READ)){
  285.         stci_d(stpcpy(Errbuf0,"Destination read error # "),error);
  286.         stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
  287.         Beep();
  288.         if (Request(Errbuf0,Errbuf1,"retry","abort")) goto WriteDestination;
  289.         else break;
  290.       }
  291.   
  292.       if (Compare(CopyBuffer,CompBuffer)){
  293.         stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
  294.         Beep();
  295.         if (Request("Verification error",Errbuf1,"retry","abort"))
  296.           goto WriteDestination;
  297.         else break;
  298.       }
  299.     }
  300.   } /* end of cylinder count loop */ /* copy done */
  301.  
  302.   DrawImage(WT->RPort,&IMTmOf,0,12);  /*  clear track window  */
  303.   RefreshWindowFrame(WT);             /*  depth gadgets back  */
  304.   if (!error){
  305.     ConPutStr(IOHist,"\n ");
  306.     ConPutStr(IOHist,Dest->VolName);
  307.     EnterHist(Dest->VolName);
  308.     Beep(0);
  309.   } else{
  310.     strcpy(Dest->VolName,"\x0eCopy unsuccesful");
  311.     Dest->DOSDisk=0;
  312.   }
  313.   ShDName(W0,D0->VolName);
  314.   ShDName(W1,D1->VolName);
  315.   MotorOff(Source);
  316.   MotorOff(Dest);
  317.   OnGadget(&GD0D1,WS,0);              /*  enable direction selection  */
  318.   GCopy.Flags&=~GADGDISABLED;
  319.   if (NowCopy){                       /*  that intuition patch again */
  320.     DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
  321.     RefOneGadget(&GCopy,WS,0);
  322.   }
  323.   return(error);
  324. }  /*  DiskCopy  */
  325.  
  326.  
  327. /*
  328.  *  Read or write one cylinder.
  329.  */
  330.  
  331. DIOCyl(drive,byte,buffer,cmd)
  332. register  DrInfo *drive; ULONG byte; char *buffer; int cmd;
  333. {
  334.   drive->Req.io_Command=cmd;
  335.   drive->Req.io_Data=(APTR)buffer; 
  336.   drive->Req.io_Length=BPCYL;
  337.   drive->Req.io_Offset=byte;
  338.   SendIO(&drive->Req);
  339.   CheckControl(0);       /* see if things did change (without track dg's) */
  340.   WaitIO(&drive->Req);
  341.   return((int)drive->Req.io_Error);
  342. }
  343.  
  344.  
  345. Compare(a,b)
  346. register  ULONG *a, *b;
  347. {
  348.   register int i;
  349.   for (i=0;i<(BPCYL/4);++i) if (*(a++)!=*(b++)) return(25); /* or 42 iyl */
  350.   return(0);
  351. }
  352.  
  353.  
  354. void MotorOff(drive)
  355. register DrInfo *drive;
  356. {
  357.   drive->Req.io_Command=TD_MOTOR;
  358.   drive->Req.io_Length=0;
  359.   DoIO(&drive->Req);
  360. }
  361.  
  362.  
  363. /*
  364.  *  Set present time and date in the creation and last changed field
  365.  *  If the bitmap is -1, it is set to +1. A new checksum is calculated.
  366.  */
  367.  
  368. void ChangeRoot(sector)
  369. register ULONG *sector;
  370. {
  371. register  ULONG *ptr, sum, i;
  372.  
  373.   DateStamp(§or[ROOT_ALTDAYS]);
  374.   sector[ROOT_CRTDAYS]=sector[ROOT_ALTDAYS];
  375.   sector[ROOT_CRTMINS]=sector[ROOT_ALTMINS];
  376.   sector[ROOT_CRTTICKS]=sector[ROOT_ALTTICKS];
  377.   if (sector[ROOT_BMFFLAG]==-1) sector[ROOT_BMFFLAG]=1;
  378.  
  379.   for (ptr=sector,sector[ROOT_CHKSUM]=0,sum=0,i=0;i<LPSECTOR;++i)
  380.     sum+=*(ptr++);
  381.   sector[ROOT_CHKSUM]=0-sum;
  382. }    /*  ChangeRoot()  */    
  383.  
  384.  
  385. /*
  386.  *  First see to get two drives. Then init (alloc) the DrInfo-structures,
  387.  *  set drive names on their places (Now in.. windows and direction g's),
  388.  *  Call OpenUser(), which opens the windows and get data buffers.
  389.  */
  390.  
  391. Init(){
  392.   register short error=0;
  393.  
  394.   if ((IntuitionBase=(struct IntuitionBase *)
  395.       OpenLibrary("intuition.library",0))==NULL)  return(-1);
  396.  
  397.   if (!AskDrives()){
  398.     if (!(D0=OpenDrive(DriveName[0],DriveNr[0])))  ++error;
  399.     if (!(D1=OpenDrive(DriveName[1],DriveNr[1])))  ++error;
  400.   } else ++error;
  401.   if (error){
  402.     Request("Pcopy did not get","two drives","OK","OK");
  403.     return(-1);
  404.   }
  405.   ITDr0.IText=D0->DevName;
  406.   strcpy(&Tx0[9],D0->DevName);
  407.   Tx0[13]=' ';
  408.   ITDr1.IText=D1->DevName;
  409.   strcpy(&Tx1[9],D1->DevName);
  410.   Tx1[13]=' ';
  411.   error=OpenUser();
  412.   if (!(CopyBuffer=(ULONG *)AllocMem(BPCYL,MEMF_CHIP))) ++error;
  413.   if (!(CompBuffer=(ULONG *)AllocMem(BPCYL,MEMF_CHIP))) ++error;
  414.   if (!(Hist=(char *)AllocMem(MHIST*MVOLNAME,PUBCLR))) ++error;
  415.   if (error)  Request("Pcopy did not get","enough memory","OK","OK");
  416.   return(error);
  417. }    /*  Init()  */
  418.  
  419.  
  420. /* 
  421.  *  Give it all back.
  422.  */
  423. void Quit()
  424. {
  425.   CloseUser();
  426.   if (D0)  CloseDrive(D0);
  427.   if (D1)  CloseDrive(D1);
  428.   if (Hist)        FreeMem(Hist,MHIST*MVOLNAME);
  429.   if (CopyBuffer)  FreeMem(CopyBuffer,BPCYL);
  430.   if (CompBuffer)  FreeMem(CompBuffer,BPCYL);
  431.   if (IntuitionBase) CloseLibrary(IntuitionBase);
  432. }
  433.  
  434.  
  435. /*
  436.  *  Allocate space for the structure, inhibit DOS, setup trackdisk port
  437.  *  and open trackdisk.
  438.  */
  439.  
  440. DrInfo *OpenDrive(DrName,Unit)
  441. char *DrName; int Unit;
  442. {
  443.   register  DrInfo *NewDr=0;
  444.  
  445.   if (NewDr=(DrInfo *)AllocMem(sizeof(DrInfo),PUBCLR)){
  446.     NewDr->DevName=DrName;
  447.     NewDr->DOSInhbt=dos_packet(DeviceProc(DrName),ACTION_INHIBIT,DOSTRUE);
  448.     NewDr->Req.io_Message.mn_Node.ln_Type=NT_MESSAGE;
  449.     NewDr->Req.io_Message.mn_Node.ln_Pri=0;
  450.     if (NewDr->Req.io_Message.mn_ReplyPort=CreatePort(0,0)){
  451.       if (!(NewDr->Device=OpenDevice(TD_NAME,Unit,&NewDr->Req,1))){
  452.       }
  453.     }
  454.   }
  455.   return(NewDr);
  456. }    /*  OpenDrive()  */
  457.  
  458.  
  459. /*
  460.  *  Close trackdisk device and get rid of memory and ports involved.
  461.  */
  462.  
  463. void CloseDrive(drive)
  464. register  DrInfo *drive;
  465. {
  466.   if (!drive->Device){
  467.     MotorOff(drive);
  468.     CloseDevice(&drive->Req);
  469.   }
  470.   if (drive->Req.io_Message.mn_ReplyPort)
  471.     DeletePort(drive->Req.io_Message.mn_ReplyPort);
  472.   FreeMem(drive,sizeof(DrInfo));
  473.   dos_packet(DeviceProc(drive->DevName),ACTION_INHIBIT,DOSFALSE);
  474. }   /*  CloseDrive  */
  475.  
  476.  
  477. /*
  478.  *  Check if a start-copy condition occured. If so call the copy routine.
  479.  */
  480.  
  481. void CheckCopy()
  482. {
  483.   register DrInfo *Source, *Dest; register short DoCopy;
  484.   if (D0->Present&&D1->Present){  /* determine direction  */
  485.     if (ITDr1.FrontPen==DESTCOLOR){
  486.       Source=D0;
  487.       Dest=D1;
  488.     } else{
  489.       Source=D1;
  490.       Dest=D0;
  491.     }
  492.     DoCopy=0;  /* three values: FALSE/WAIT/NOWAIT  */
  493.     if ((GAuto.Flags&SELECTED)&&EnAuto){
  494.       if (GUnRd.Flags&SELECTED){
  495.         if (!Dest->Readable) DoCopy=NOWAIT;
  496.       } else if (GNDOS.Flags&SELECTED){
  497.         if (!Dest->DOSBoot) DoCopy=NOWAIT;
  498.       } else  DoCopy=(Dest->DOSDisk)?WAIT:NOWAIT;
  499.     } else if (GCopy.Flags&SELECTED){
  500.       GCopy.Flags&=~SELECTED;
  501.       DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
  502.       RefOneGadget(&GCopy,WS,0);
  503.       DoCopy=NOWAIT;
  504.     }
  505.     if (DoCopy)  DiskCopy(Source,Dest,DoCopy);
  506.     EnAuto=0;
  507.   }
  508. }
  509.  
  510.  
  511. /*
  512.  *  Show disk name in Now in ..  window, or clear it
  513.  */
  514.  
  515. void ShDName(W,text)
  516. struct Window *W; register char *text;
  517. {
  518. static struct IntuiText ITDiskName={ 1,0,JAM2,0,0,0,0,0 };
  519. static struct Image IMDBlank={ 0,0,WD0-4,8,0,0,0,0,0 };
  520.   DrawImage(W->RPort,&IMDBlank,2,11);
  521.   if (text){
  522.     if (*text=='\x0e'){
  523.       ITDiskName.FrontPen=2;
  524.       ++text;
  525.     } else  ITDiskName.FrontPen=1;
  526.     ITDiskName.IText=text;
  527.     PrintIText(W->RPort,&ITDiskName,12,11);
  528.   }
  529. }
  530.  
  531.  
  532. /*  end of pcopy.c  */
  533.